home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2000 #4
/
Amiga Plus CD - 2000 - No. 4.iso
/
Vollversion
/
CamD
/
development
/
examples
/
drum
/
timer.a
< prev
next >
Wrap
Text File
|
2000-05-15
|
7KB
|
192 lines
;* ============================================================================ *
; Deluxe Music Construction Set II
; timer.asm -- CIA timer interrupt
; By Talin.
;* ============================================================================ */
include "exec/types.i"
include "exec/tasks.i"
include "dos/dos.i"
include "libraries/realtime.i"
xdef _TimeServer
xdef _CalcClockIncrement
xref _tempo_rate
xref _mclock_pos
xref _mclock_accumulator
xref _mclocks_per_column
xref _pattern_mclocks
xref _current_pattern_start
xref _current_pattern_end
xref _pattern_pos
xref _column_pos
xref _clock_pos
xref _main_task
xref _clock_state
xref _SysBase
xref _LVOSignal
SECTION text,CODE
_TimeServer
move.l pmt_Method(a1),d0 ; d0 <-- method id
cmp.l #PM_TICK,d0 ; is it a tick message?
bne 10$
;---------- determine the number of ticks which have occured since
; the last time this hook was called.
move.l pmt_Time(a1),d0 ; d0 <-- current clock time
bmi 2$ ; DMCS doesn't deal with negative time...
move.l _clock_pos,d1 ; d1 <-- time of last call
sub.l d1,d0 ; d0 <-- time since last call
bmi 2$ ; if clock went backwards, ignore...
add.l d0,_clock_pos ; update accumulated time
;---------- Check to see if we're the Maestro
* move.l pl_Source(a2),a0 ; a0 <-- Conductor
* btst.b #CONDUCTB_METROSET,cdt_Flags+1(a0) ; if metronome already set
* beq.s 1$
* move.l cdt_Metronome(a0),d0 ; d0 <-- current metronome time
* move.l d0,pl_MetricTime(a2) ; update playerinfo w/ time
* bra.s 4$
; d0 now equals the number of ticks since the last time we updated _clock_pos.
; use this to do an extended precision multiply...
move.l d0,d1 ; get copy of delta time
swap d1 ; get upper half
mulu.w _tempo_rate,d1 ; do extended precision math.
swap d1 ; put extended part in upper
clr.w d1 ; half of d1
mulu.w _tempo_rate,d0 ; d0 <-- musical ticks since last
add.l d1,d0 ; add extended precision part.
; d0 has now been converted to a delta-mclocks * 256
add.l _mclock_accumulator,d0 ; d0 <-- total elapsed musical time
move.l d0,_mclock_accumulator ; update tempo_accumulator
; d0 now contains to total elapsed mclocks.
asr.l #8,d0 ; convert fixed-point to integer
;---------- since we're musically aware, update the "conducted" bit.
; move.l d0,cdt_Metronome(a0) ; update conductor metronome
; bset.b #CONDUCTB_METROSET,cdt_Flags+1(a0) ; set metronome flag
cmp.l pl_MetricTime(a2),d0 ; see if they are the same
beq.s 2$ ; no point in waking up if they are.
4$ move.l d0,pl_MetricTime(a2) ; see if they are the same
;---------- See if we overflowed into the next pattern
5$ cmp.l _current_pattern_end,d0 ; see if we're at the frame end
blt.s 6$
add.l #1,_pattern_pos ; add 1 to pattern position
; new start <-- old end
move.l _current_pattern_end,_current_pattern_start
; new end += pattern size
move.l _pattern_mclocks,d1
add.l d1,_current_pattern_end
bra.s 5$
;---------- calculate the column # within the pattern
6$ sub.l _current_pattern_start,d0 ; clocks in this pattern
divu _mclocks_per_column,d0 ; get column #
cmp.w _column_pos,d0 ; see if column # changed
beq.s 2$ ; if so
move.w d0,_column_pos ; then update column # and signal
;---------- get ExecBase into a6.
move.l a6,-(sp)
move.l _SysBase,a6
;---------- signal main task that a state change has occurred
move.l _main_task,a1 ; address of player task
move.l #SIGBREAKF_CTRL_F,d0 ; signal to send
CALLLIB _LVOSignal ; wake up player task
;---------- restore a6 register
move.l (sp)+,a6
;---------- just exit
2$ moveq #0,d0
rts
10$ cmp.l #PM_STATE,d0 ; is it a state-change message?
bne.s 20$
;---------- get ExecBase into a6.
move.l a6,-(sp)
move.l _SysBase,a6
;---------- signal main task that a state change has occurred
move.l _main_task,a1 ; address of player task
move.l #SIGBREAKF_CTRL_E,d0 ; signal to send
CALLLIB _LVOSignal ; wake up player task
;---------- restore a6 register
move.l (sp)+,a6
;---------- return from hook
moveq #0,d0 ; end server chain???
rts
20$
; cmp.l #PM_POSITION,d0 ; is it a special locate?
; bne.s 30$
;
;;---------- handle special locate message
;
; move.l pmt_Time(a1),_special_locate_time
;
; move.l a6,-(sp)
; move.l _SysBase,a6
;
;;---------- signal player task that a state change has occurred
;
; move.l _player_task,a1 ; address of player task
; move.l #SIGF_INTUITION,d0 ; signal to send
; Call Signal ; wake up player task
;
;;---------- restore a6 register
;
; move.l (sp)+,a6
;---------- return from hook
30$ moveq #0,d0 ; end server chain???
rts
_CalcClockIncrement ; (music delta)
; move.l 4(sp),d0 ; d0 <-- musical ticks
; lsl.l #8,d0 ; d0 <-- musical ticks * 256
; add.l _time_remainder,d0 ; plus remaining ticks
; divu.w _tempo_rate+2,d0 ; d0.w <-- real-time ticks
; swap.w d0 ; get remainder
; move.w d0,_time_remainder+2 ; put remainder into time remainder
; clr.w d0 ; clear lower half d0
; swap.w d0 ; d0.l <--real-time ticks
; rts
end